﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace ExcelToData
{
    public abstract class BaseConfig<T> where T : new()
    {
        private static readonly T singleton = new T();
        public static T Singleton
        {
            get
            {
                return singleton;
            }
        }
        #region 属性
        /// <summary>
        /// 文件路径(包含文件名)
        /// </summary>
        abstract protected string ConfigPath
        { get; }

        /// <summary>    /// 文件名    /// </summary>
        protected string ConfigFileName
        { get; }

        /// <summary>
        /// 根目录(根节点名)
        /// </summary>
        protected string rootXmlNode
        { get; }


        /// <summary>
        /// 配置的值
        /// </summary>
        public Dictionary<string, string> ConfigValue;

        #endregion

        /// <summary>    /// 构造和本地加载     /// </summary>
        /// <param name="ConfigPath"></param>
        protected BaseConfig()
        {
            FileInfo info = new FileInfo(ConfigPath);
            ConfigFileName = info.Name;
            rootXmlNode = info.Name.Replace(info.Extension, "");
            ConfigValue = new Dictionary<string, string>();
            InitDefaultValueForThisDictionary(ref ConfigValue);//配置子类的值
            LoadFile();//载入文件
        }

        /// <summary>
        /// 配置字典,配置的初值即是默认值
        /// </summary>
        protected abstract void InitDefaultValueForThisDictionary(ref Dictionary<string, string> ConfigValue);


        #region 数据获取

        void logError(string key, string configFileName)
        {
            Console.WriteLine(string.Format("{0}--此key不存在{1}", key, configFileName));
        }

        /// <summary>
        /// 获取byte类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public byte GetConfigByte(string key)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
            {
                byte byteVal;
                if (byte.TryParse(strValue, out byteVal))
                {
                    return byteVal;
                }
                else
                {
                    logError(key + "的值不能转换为byte", ConfigFileName);
                    return 0;
                }
            }
            else
            {
                logError(key, ConfigFileName);
                return 0;
            }
        }

        /// <summary>
        /// 获取sbyte类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public sbyte GetConfigSbyte(string key)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
            {
                sbyte byteVal;
                if (sbyte.TryParse(strValue, out byteVal))
                {
                    return byteVal;
                }
                else
                {
                    logError(key + "的值不能转换为byte", ConfigFileName);
                    return 0;
                }
            }
            else
            {
                logError(key, ConfigFileName);
                return 0;
            }
        }
        /// <summary>
        /// 获取short类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public short GetConfigShort(string key)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
            {
                short shortVal;
                if (short.TryParse(strValue, out shortVal))
                {
                    return shortVal;
                }
                else
                {
                    logError(key + "的值不能转换为short", ConfigFileName);
                    return 0;
                }
            }
            else
            {
                logError(key, ConfigFileName);
                return 0;
            }
        }
        /// <summary>
        /// 获取ushort类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public ushort GetConfigUshort(string key)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
            {
                ushort ushortVal;
                if (ushort.TryParse(strValue, out ushortVal))
                {
                    return ushortVal;
                }
                else
                {
                    logError(key + "的值不能转换为short", ConfigFileName);
                    return 0;
                }
            }
            else
            {
                logError(key, ConfigFileName);
                return 0;
            }
        }
        /// <summary>
        /// 获取int类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public int GetConfigInt(string key)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
            {
                int intVal;
                if (int.TryParse(strValue, out intVal))
                {
                    return intVal;
                }
                else
                {
                    logError(key + "的值不能转换为int", ConfigFileName);
                    return 0;
                }
            }
            else
            {
                logError(key, ConfigFileName);
                return 0;
            }
        }
        /// <summary>
        /// 获取uint类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public uint GetConfigUint(string key)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
            {
                uint uintVal;
                if (uint.TryParse(strValue, out uintVal))
                {
                    return uintVal;
                }
                else
                {
                    logError(key + "的值不能转换为int", ConfigFileName);
                    return 0;
                }
            }
            else
            {
                logError(key, ConfigFileName);
                return 0;
            }
        }
        /// <summary>
        /// 获取float类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public float GetConfigFloat(string key)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
            {
                float floatVal;
                if (float.TryParse(strValue, out floatVal))
                {
                    return floatVal;
                }
                else
                {
                    logError(key + "的值不能转换为float", ConfigFileName);
                    return 0;
                }
            }
            else
            {
                logError(key, ConfigFileName);
                return 0;
            }
        }

        /// <summary>
        /// 获取string类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetConfigString(string key)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
                return strValue;
            else
            {
                logError(key, ConfigFileName);
                return strValue;
            }
        }

        /// <summary>
        /// 获取bool类型值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool GetConfigBool(string key)
        {
            string boolValue = string.Empty;
            if (ConfigValue.TryGetValue(key, out boolValue))
            {
                boolValue = boolValue.ToLower();
                bool result = false;
                if (boolValue == "true" || boolValue == "1")
                    result = true;
                return result;
            }
            else
            {
                logError(key, ConfigFileName);
                return false;
            }
        }

        /// <summary>
        /// 获取list类型,字符串中间用标记分开
        /// </summary>
        /// <param name="key"></param>
        /// <param name="SplitSign"></param>
        /// <returns></returns>
        public List<string> GetConfigStringList(string key, char SplitSign)
        {
            string strValue;
            if (ConfigValue.TryGetValue(key, out strValue))
            {
                return new List<string>(strValue.Split(SplitSign));
            }
            else
            {
                logError(key, ConfigFileName);
                return new List<string>();
            }
        }
        #endregion

        #region 数据设定

        public void SetConfigValue(string key, string Value)
        {
            if (ConfigValue.ContainsKey(key))
            {
                ConfigValue[key] = Value;
            }
            else
            {
                Console.WriteLine("设定配置值" + key + "不存在");
            }
        }

        #endregion


        #region 文件

        /// <summary>
        /// 创建文件
        /// </summary>
        protected virtual void CreateFile(string rootXmlNode, string filePath)
        {
            FileInfo info = new FileInfo(filePath);

            if (!Directory.Exists(info.Directory.FullName))
            {
                Directory.CreateDirectory(info.Directory.FullName);
            }

            XmlDocument xml = new XmlDocument();
            XmlDeclaration decl = xml.CreateXmlDeclaration("1.0", "utf-8", null);
            xml.AppendChild(decl);
            XmlElement rootEle = xml.CreateElement(rootXmlNode);
            xml.AppendChild(rootEle);
            foreach (var item in ConfigValue)
            {
                XmlElement childEle = xml.CreateElement(item.Key);
                childEle.InnerText = item.Value;
                rootEle.AppendChild(childEle);
            }
            xml.Save(filePath);
        }


        public void SaveConfig()
        {
            Console.WriteLine("保存默认配置文件: " + ConfigFileName);
            CreateFile(rootXmlNode, ConfigPath);
        }


        /// <summary>    /// 载入文件 填充字典    /// </summary>
        protected virtual void LoadFile()
        {
            if (File.Exists(ConfigPath))
            {
                XmlDocument doc = Filer.Singleton.ReadXmlFile(ConfigPath);
                XmlNode root = doc.SelectSingleNode(rootXmlNode);
                Dictionary<string, string> xmlcontent = new Dictionary<string, string>();
                foreach (XmlNode node in root.ChildNodes)
                {
                    xmlcontent[node.LocalName] = node.InnerText;
                }

                //将配置中的内容赋给字典
                foreach (var item in xmlcontent)
                {
                    if (xmlcontent.ContainsKey(item.Key))
                    {
                        ConfigValue[item.Key] = xmlcontent[item.Key];
                    }
                }
            }
            else
            {
                Console.WriteLine("生成默认配置文件: " + ConfigFileName);
                CreateFile(rootXmlNode, ConfigPath);
            }
        }

        #endregion





    }
}